<script lang="ts" setup name="myMap">
import { mapContextKey } from './hooks/constants'
import Map, { type MapOptions } from 'ol/Map'
import View, { ViewOptions } from 'ol/View'
import { FullScreen, Zoom } from 'ol/control'
import TileLayer from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import 'ol/ol.css'

const tdtTK = '464554f64aa4f4e90e0321c17a57a331'
// const tdtTK = 'e90d56e5a09d1767899ad45846b0cefd'

defineOptions({
  name: 'MyMap'
})

const props = defineProps<{
  mapOptions?: MapOptions
  viewOptions?: ViewOptions
  defaultLayer?: Boolean
}>()

const emits = defineEmits(['init'])

const layers = [
  new TileLayer({
    source: new XYZ({
      url: `http://t{0-7}.tianditu.com/DataServer?T=vec_c&x={x}&y={y}&l={z}&tk=${tdtTK}`,
      projection: 'EPSG:4326',
      maxZoom: 18
    })
  }),
  new TileLayer({
    source: new XYZ({
      url: `http://t{0-7}.tianditu.com/DataServer?T=cva_c&x={x}&y={y}&l={z}&tk=${tdtTK}`,
      projection: 'EPSG:4326',
      maxZoom: 18
    }),
    zIndex: 999
  })
]

let map: Map | undefined = new Map({
  controls: [new Zoom(), new FullScreen()],
  ...props.mapOptions,
  layers: layers,
  view: new View({
    center: [116.252, 39.542],
    projection: 'EPSG:4326',
    zoom: 8,
    minZoom: 1,
    maxZoom: 20,
    ...props.viewOptions
  })
})

provide(mapContextKey, map)

const mapRef = shallowRef<HTMLElement>()

/**
 * 地图挂载
 */
onMounted(() => {
  map?.setTarget(mapRef.value)
  emits('init', map)
})

/**
 * 组件销毁、卸载地图
 */
onUnmounted(() => {
  map?.setTarget(undefined)
  map = undefined
})

const render = () => map?.render()
const updateSize = () => map?.updateSize()

defineExpose({
  map,
  mapRef,
  render,
  updateSize
})
</script>

<template>
  <div class="my-map-wrap">
    <div class="map" ref="mapRef"></div>
    <slot></slot>
  </div>
</template>

<style lang="scss" scoped>
.my-map-wrap,
.map {
  position: relative;
  height: 100%;
}

.ol-zoom {
  top: 8px;
  left: 8px;
  font-size: 26px;
}

.ol-full-screen {
  top: 82px;
  right: auto;
  left: 8px;
  font-size: 26px;
}
</style>
